
-- ========================================================================= --
-- Copyright © 2009 Thomas ROBERT                                            --
-- ========================================================================= --
-- This file is part of FyLooter.                                            --
--                                                                           --
-- FyLooter is free software: you can redistribute it and/or modify it under --
-- the terms of the GNU General Public License as published by the Free      --
-- Software Foundation, either version 3 of the License, or (at your option) --
-- any later version.                                                        --
--                                                                           --
-- FyLooter is distributed in the hope that it will be useful, but WITHOUT   --
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     --
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for  --
-- more details.                                                             --
--                                                                           --
-- You should have received a copy of the GNU General Public License along   --
-- with FyLooter. If not, see <http://www.gnu.org/licenses/>.                --
-- ========================================================================= --

FyLooter.Gui.SCROLL_ITEM_COUNT = 10;

-- ------------------------------------------------------------------------- --
-- 
-- ------------------------------------------------------------------------- --

function FyLooter.Gui:SetModel(model)
  self.Model = model;

  self.Model:Update();
  self:Update();
end

-- ------------------------------------------------------------------------- --

function FyLooter.Gui:Update()
  if (not self.ScrollArea:IsVisible()) then return end

  local numItems = self.Model:GetNumItems();

  local max = numItems - self.SCROLL_ITEM_COUNT;

  if (max > 0) then
    self.ScrollSlider:SetMinMaxValues(0, max);
    self.ScrollBar:Show();
  else
    self.ScrollSlider:SetMinMaxValues(0, 0);
    self.ScrollBar:Hide();
  end

  local offset = self.ScrollSlider:GetValue();

  for i = 1, self.SCROLL_ITEM_COUNT do
    local idx = offset + i;
    local item = self.ScrollItems[i];

    if (idx > numItems) then
      item:Hide();
    else
      local t = item:GetNormalTexture();
      t:SetVertexColor(0.5, 0.5, 0.5, 0.5);

      local player, character, level, class, color, hasChild, isExpanded, status = self.Model:GetItemInfo(idx);
      
      if (not character) then
        if (hasChild) then
          if (isExpanded) then
            item.ExpandButton:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");
            item.ExpandButton:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-Down");
          else
            item.ExpandButton:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
            item.ExpandButton:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-Down");
          end

          item.ExpandButton:Show();
        else
          item.ExpandButton:Hide();
        end

        item.NameLabel:SetFontObject(GameFontNormalSmall);
        item.NameLabel:SetText(player);

        item.LevelLabel:Hide();
        item.ClassLabel:Hide();
      else
        item.ExpandButton:Hide();

        item.NameLabel:SetFontObject(GameFontHighlightSmall);
        item.NameLabel:SetText(character);

        if (level > 0) then
          item.LevelLabel:SetText(level);
          item.LevelLabel:Show();
        else
          item.LevelLabel:Hide();
        end

        if (class) then
          item.ClassLabel:SetText(class);
          item.ClassLabel:SetTextColor(color.r, color.g, color.b);
          item.ClassLabel:Show();
        else
          item.ClassLabel:Hide();
        end

        local t = item:GetNormalTexture();

        if (status == FyLooter.Status.NEED) then
          t:SetVertexColor(0.5, 1, 0.5, 0.5);
        elseif (status == FyLooter.Status.GREED) then
          t:SetVertexColor(0.5, 0.5, 1, 0.5);
        elseif (status == FyLooter.Status.PASS) then
          t:SetVertexColor(1, 0.5, 0.5, 0.5);
        end
      end

      if (idx == self.Model:GetSelection()) then
        item:LockHighlight();
      else
        item:UnlockHighlight();
      end

      item:Show();
    end
  end
end

-- ------------------------------------------------------------------------- --

function FyLooter.Gui:SetLoot(loot)
  self.MinimapButton:Disable()
  self.MainFrame:Hide();

  self:SetModel(FyLooter.Model.Candidates);

  self.Loot = loot;

  local name, _, quality, _, _, _, _, _, _, texture = GetItemInfo(self.Loot.item);
  local color = ITEM_QUALITY_COLORS[quality];

  self.LootIcon:SetTexture(texture);
  self.LootLabel:SetText(name);
  if (color) then
    self.LootLabel:SetTextColor(color.r, color.g, color.b);
  end

  self.LootFrame:Show();
  self.RollFrame:Show();

  self.MainFrame:Show();
end

-- ------------------------------------------------------------------------- --
--
-- ------------------------------------------------------------------------- --

local function OkButton_OnClick(self)
  FyLooter.Gui.MainFrame:Hide();
end

-- ------------------------------------------------------------------------- --

local function AdminFrame_OkButton_OnClick(self)
  FyLooter:Delete(FyLooter.Core.backup);

  FyLooter.Core:CommitPlayers();

  FyLooter.Gui.MainFrame:Hide();
end

-- ------------------------------------------------------------------------- --

local function AdminFrame_CancelButton_OnClick(self)
  if (FyLooter.Core.uncommitedChanges) then
    FyLooter.Data.players = FyLooter.Core.backup;
    FyLooter.Gui.Model:Update();
  end

  FyLooter:Delete(FyLooter.Core.backup);

  FyLooter.Gui.MainFrame:Hide();
end

-- ------------------------------------------------------------------------- --

local function InsertFrame_OkButton_OnClick(self)
  FyLooter.Gui.Model:Insert(FyLooter.Gui.PlayerEditBox:GetText(), FyLooter.Gui.CharacterEditBox:GetText());
  FyLooter.Gui.CharacterEditBox:SetText("");

  FyLooter.Gui.OkButton:SetScript("OnClick", AdminFrame_OkButton_OnClick);    
  FyLooter.Gui.CancelButton:SetScript("OnClick", AdminFrame_CancelButton_OnClick);
  
  FyLooter.Gui.InsertFrame:Hide();
  FyLooter.Gui.ScrollArea:Show();
  FyLooter.Gui.AdminFrame:Show();

  FyLooter.Gui:Update();
end

-- ------------------------------------------------------------------------- --

local function InsertFrame_CancelButton_OnClick(self)
  FyLooter.Gui.OkButton:SetScript("OnClick", AdminFrame_OkButton_OnClick);
  FyLooter.Gui.CancelButton:SetScript("OnClick", AdminFrame_CancelButton_OnClick);

  FyLooter.Gui.InsertFrame:Hide();
  FyLooter.Gui.ScrollArea:Show();
  FyLooter.Gui.AdminFrame:Show();
end

-- ------------------------------------------------------------------------- --
-- MinimapButton
-- ------------------------------------------------------------------------- --

local function MinimapButton_OnEnter(self)
  if (not self.dragging) then
    GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT");
    GameTooltip:SetText("FyLooter", 1, 1, 1);
    GameTooltip:Show();
  end
end

-- ------------------------------------------------------------------------- --

local function MinimapButton_OnLeave(self)
  GameTooltip:Hide();
end

-- ------------------------------------------------------------------------- --

local function MinimapButton_OnClick(self)
  local mainFrame = FyLooter.Gui.MainFrame;

  if (not mainFrame:IsVisible()) then
    FyLooter.Model.Characters:Update();

    FyLooter.Gui:SetModel(FyLooter.Model.Characters);
    
    FyLooter.Gui.ScrollArea:Show();

    if (IsControlKeyDown() and FyLooter.ADMIN) then
      FyLooter.Core.backup = FyLooter:Clone(FyLooter.Data.players);

      FyLooter.Gui.OkButton:SetScript("OnClick", AdminFrame_OkButton_OnClick);
      FyLooter.Gui.CancelButton:SetScript("OnClick", AdminFrame_CancelButton_OnClick);

      FyLooter.Gui.OkButton:SetText("Ok");

      FyLooter.Gui.AdminFrame:Show();
      FyLooter.Gui.CancelButton:Show();
    else
      FyLooter.Gui.OkButton:SetScript("OnClick", OkButton_OnClick);

      FyLooter.Gui.OkButton:SetText("Close");

      FyLooter.Gui.CancelButton:Hide();
    end

    FyLooter.Gui.ControlFrame:Show();

    mainFrame:Show();
  end
end

-- ------------------------------------------------------------------------- --

local function MinimapButton_OnUpdate(self)
  local px, py = GetCursorPosition();
	local mx, my = Minimap:GetCenter();
	local scale  = Minimap:GetEffectiveScale();

  local a = math.rad(math.deg(math.atan2(py / scale - my, px / scale - mx)) % 360);
  local r = 80 * scale;

  self:SetPoint("CENTER", r * math.cos(a), r * math.sin(a));
end

-- ------------------------------------------------------------------------- --
local function MinimapButton_OnDragStart(self)
  self.dragging = true;
  self:LockHighlight();
  self:SetScript("OnUpdate", MinimapButton_OnUpdate);

  GameTooltip:Hide();
end

-- ------------------------------------------------------------------------- --

local function MinimapButton_OnDragStop(self)
  self:SetScript("OnUpdate", nil);
  self:UnlockHighlight();
  self.dragging = false;

  local x, y = select(4, self:GetPoint(1));

  FyLooter.Data.settings.mmb[1] = x;
  FyLooter.Data.settings.mmb[2] = y;
end

-- ------------------------------------------------------------------------- --
-- MainFrame
-- ------------------------------------------------------------------------- --

local function MainFrame_OnHide(self)
  FyLooter.Gui.ScrollArea:Hide();
  FyLooter.Gui.LootFrame:Hide();
  FyLooter.Gui.RollFrame:Hide();
  FyLooter.Gui.MasterFrame:Hide();
  FyLooter.Gui.AdminFrame:Hide();
  FyLooter.Gui.InsertFrame:Hide();
  FyLooter.Gui.ControlFrame:Hide();

  local model = FyLooter.Gui.Model;
  if (model) then model:SetSelection(nil) end
end

-- ------------------------------------------------------------------------- --
-- TitleFrame
-- ------------------------------------------------------------------------- --

local function TitleFrame_OnMouseDown(self, button)
  if (button == "LeftButton") then
    FyLooter.Gui.MainFrame:StartMoving();
  end
end

-- ------------------------------------------------------------------------- --

local function TitleFrame_OnMouseUp(self, button)
  if (button == "LeftButton") then
    FyLooter.Gui.MainFrame:StopMovingOrSizing();
  end
end

-- ------------------------------------------------------------------------- --
-- ScrollArea
-- ------------------------------------------------------------------------- --

local function ScrollArea_OnShow(self)
  FyLooter.Gui.LootFrame:SetPoint("TOPLEFT", self, "BOTTOMLEFT");
  FyLooter.Gui.LootFrame:SetPoint("TOPRIGHT", self, "BOTTOMRIGHT");

  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() + self:GetHeight());

  FyLooter.Gui:Update();
end

-- ------------------------------------------------------------------------- --

local function ScrollArea_OnHide(self)
  FyLooter.Gui.LootFrame:SetPoint("TOPLEFT", FyLooter.Gui.TitleFrame, "BOTTOMLEFT");
  FyLooter.Gui.LootFrame:SetPoint("TOPRIGHT", FyLooter.Gui.TitleFrame, "BOTTOMRIGHT");

  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() - self:GetHeight());
end

-- ------------------------------------------------------------------------- --
-- ScrollView
-- ------------------------------------------------------------------------- --

local function ScrollView_OnMouseWheel(self, delta)
  FyLooter.Gui.ScrollSlider:SetValue(FyLooter.Gui.ScrollSlider:GetValue() - delta);
end

-- ------------------------------------------------------------------------- --
-- ScrollItems
-- ------------------------------------------------------------------------- --

local function ScrollItem_OnClick(self)
  local idx = self:GetID() + FyLooter.Gui.ScrollSlider:GetValue();
  local sel = FyLooter.Gui.Model:GetSelection();

  if (idx == sel) then
    FyLooter.Gui.Model:SetSelection(nil);
  else
    FyLooter.Gui.Model:SetSelection(idx);
  end

  FyLooter.Gui:Update();
end

-- ------------------------------------------------------------------------- --

local function ExpandButton_OnClick(self)
  local idx = self:GetParent():GetID() + FyLooter.Gui.ScrollSlider:GetValue();

  local isExpanded = select(7, FyLooter.Gui.Model:GetItemInfo(idx));

  if (isExpanded) then
    FyLooter.Gui.Model:Collapse(idx);
  else
    FyLooter.Gui.Model:Expand(idx);
  end

  FyLooter.Gui.Model:SetSelection(idx);

  FyLooter.Gui:Update();
end

-- ------------------------------------------------------------------------- --
-- ScrollBar
-- ------------------------------------------------------------------------- --

local function ScrollBar_OnShow(self)
  FyLooter.Gui.ScrollView:SetPoint("BOTTOMRIGHT", -self:GetWidth(), 0);
end

-- ------------------------------------------------------------------------- --

local function ScrollBar_OnHide(self)
  FyLooter.Gui.ScrollView:SetPoint("BOTTOMRIGHT", 0, 0);
end

-- ------------------------------------------------------------------------- --
-- ScrollUpButton
-- ------------------------------------------------------------------------- --

local function ScrollUpButton_OnClick(self, button, down)
  FyLooter.Gui.ScrollSlider:SetValue(FyLooter.Gui.ScrollSlider:GetValue() - 1);
end

-- ------------------------------------------------------------------------- --
-- ScrollDownButton
-- ------------------------------------------------------------------------- --

local function ScrollDownButton_OnClick(self, button, down)
  FyLooter.Gui.ScrollSlider:SetValue(FyLooter.Gui.ScrollSlider:GetValue() + 1);
end

-- ------------------------------------------------------------------------- --
-- ScrollSlider
-- ------------------------------------------------------------------------- --

local function ScrollSlider_OnValueChanged(self, value)
  FyLooter.Gui:Update();
end

-- ------------------------------------------------------------------------- --
-- LootFrame
-- ------------------------------------------------------------------------- --

local function LootFrame_OnShow(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() + self:GetHeight());
end

-- ------------------------------------------------------------------------- --

local function LootFrame_OnHide(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() - self:GetHeight());
end

-- ------------------------------------------------------------------------- --

local function LootIcon_OnEnter(self)
  GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
  GameTooltip:SetHyperlink(FyLooter.Gui.Loot.item);
  GameTooltip:Show();
end

-- ------------------------------------------------------------------------- --

local function LootIcon_OnLeave(self)
  GameTooltip:Hide();
end

-- ------------------------------------------------------------------------- --
-- MasterFrame
-- ------------------------------------------------------------------------- --

local function MasterFrame_OnShow(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() + self:GetHeight());
end

-- ------------------------------------------------------------------------- --

local function MasterFrame_OnHide(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() - self:GetHeight());
end

-- ------------------------------------------------------------------------- --

local function PayButton_OnClick(self)
  local idx = FyLooter.Gui.Model:GetSelection();

  GiveMasterLoot(FyLooter.Gui.Loot.slot, FyLooter.Gui.Model.index[idx]);

  FyLooter.Gui.Model:Kill(idx);

  FyLooter:SendCommMessage("FLer_LootCleared", FyLooter.Gui.Loot.item, "RAID");
end

-- ------------------------------------------------------------------------- --

local function FreeButton_OnClick(self)
  local idx = FyLooter.Gui.Model:GetSelection();

  GiveMasterLoot(FyLooter.Gui.Loot.slot, FyLooter.Gui.Model.index[idx]);
  
  FyLooter:SendCommMessage("FLer_LootCleared", FyLooter.Gui.Loot.item, "RAID");
end

-- ------------------------------------------------------------------------- --

local function CloseButton_OnClick(self)  
  FyLooter:SendCommMessage("FLer_LootCleared", FyLooter.Gui.Loot.item, "RAID");
end

-- ------------------------------------------------------------------------- --
-- RollFrame
-- ------------------------------------------------------------------------- --

local function RollFrame_OnShow(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() + self:GetHeight());
end

-- ------------------------------------------------------------------------- --

local function RollFrame_OnHide(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() - self:GetHeight());
end

-- ------------------------------------------------------------------------- --

local function NeedButton_OnClick(self)
  FyLooter.Core:AnswerRoll(FyLooter.Status.NEED);

  FyLooter.Gui.RollFrame:Hide();
  FyLooter.Gui.ScrollArea:Show();

  if (FyLooter.Gui.Loot.ml == UnitName("player")) then
    FyLooter.Gui.MasterFrame:Show();
  end
end

-- ------------------------------------------------------------------------- --

local function GreedButton_OnClick(self)
  FyLooter.Core:AnswerRoll(FyLooter.Status.GREED);

  FyLooter.Gui.RollFrame:Hide();
  FyLooter.Gui.ScrollArea:Show();

  if (FyLooter.Gui.Loot.ml == UnitName("player")) then
    FyLooter.Gui.MasterFrame:Show();
  end
end

-- ------------------------------------------------------------------------- --

local function PassButton_OnClick(self)
  FyLooter.Core:AnswerRoll(FyLooter.Status.PASS);

  FyLooter.Gui.RollFrame:Hide();
  FyLooter.Gui.ScrollArea:Show();

  if (FyLooter.Gui.Loot.ml == UnitName("player")) then
    FyLooter.Gui.MasterFrame:Show();
  end
end

-- ------------------------------------------------------------------------- --
-- AdminFrame
-- ------------------------------------------------------------------------- --

local function AdminFrame_OnShow(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() + self:GetHeight());
end

-- ------------------------------------------------------------------------- --

local function AdminFrame_OnHide(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() - self:GetHeight());
end

-- ------------------------------------------------------------------------- --

local function InsertButton_OnClick(self)
  FyLooter.Gui.AdminFrame:Hide();
  FyLooter.Gui.InsertFrame:Show();

  FyLooter.Gui.OkButton:SetScript("OnClick", InsertFrame_OkButton_OnClick);
  FyLooter.Gui.CancelButton:SetScript("OnClick", InsertFrame_CancelButton_OnClick);
end

-- ------------------------------------------------------------------------- --

local function RemoveButton_OnClick(self)
  FyLooter.Gui.RemoveButton:Disable();

  local idx = FyLooter.Gui.Model:GetSelection();

  FyLooter.Gui.Model:Remove(idx);

  if (idx <= FyLooter.Gui.Model:GetNumItems()) then
    FyLooter.Gui.Model:SetSelection(idx);
  else
    if (idx > 1) then
      FyLooter.Gui.Model:SetSelection(idx - 1);
    else
      FyLooter.Gui.Model:SetSelection(nil);
    end
  end

  FyLooter.Gui:Update();
end

-- ------------------------------------------------------------------------- --

local function UpButton_OnClick(self)
  FyLooter.Gui.UpButton:Disable();
  FyLooter.Gui.DownButton:Disable();

  local idx = FyLooter.Gui.Model:GetSelection();

  FyLooter.Gui.Model:Swap(idx, idx - 1);
  FyLooter.Gui.Model:SetSelection(idx - 1);

  FyLooter.Gui:Update();
end

-- ------------------------------------------------------------------------- --

local function DownButton_OnClick(self)
  FyLooter.Gui.UpButton:Disable();
  FyLooter.Gui.DownButton:Disable();

  local idx = FyLooter.Gui.Model:GetSelection();

  FyLooter.Gui.Model:Swap(idx, idx + 1);
  FyLooter.Gui.Model:SetSelection(idx + 1);

  FyLooter.Gui:Update();
end

-- ------------------------------------------------------------------------- --
-- InsertFrame
-- ------------------------------------------------------------------------- --

local function InsertFrame_OnShow(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() + self:GetHeight());

  FyLooter.Gui.CharacterEditBox:SetFocus();
end

-- ------------------------------------------------------------------------- --

local function InsertFrame_OnHide(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() - self:GetHeight());
end

-- ------------------------------------------------------------------------- --
-- ControlFrame
-- ------------------------------------------------------------------------- --

local function ControlFrame_OnShow(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() + self:GetHeight());
end

-- ------------------------------------------------------------------------- --

local function ControlFrame_OnHide(self)
  FyLooter.Gui.MainFrame:SetHeight(FyLooter.Gui.MainFrame:GetHeight() - self:GetHeight());
end

-- ------------------------------------------------------------------------- --
-- 
-- ------------------------------------------------------------------------- --

function FyLooter.Gui:SetupWidgets()
  local backdrop = {
      bgFile   = "Interface\\Tooltips\\ChatBubble-Background",
      edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
      tile     = true,
      tileSize = 16,
      edgeSize = 16,
      insets   = {
        left   = 3,
        right  = 3,
        top    = 3,
        bottom = 3,
      },
  };

  --
  -- MinimapButton
  --

  do
    self.MinimapButton = CreateFrame("Button", "FLer_MinimapButton", Minimap, "MiniMapButtonTemplate");
    self.MinimapButton:SetWidth(33);
    self.MinimapButton:SetHeight(33);
    self.MinimapButton:SetPoint("CENTER", unpack(FyLooter.Data.settings.mmb));
    self.MinimapButton:SetFrameStrata("MEDIUM");
    self.MinimapButton:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight", "ADD");
    self.MinimapButton:RegisterForDrag("RightButton");
    self.MinimapButton:SetScript("OnEnter", MinimapButton_OnEnter);
    self.MinimapButton:SetScript("OnLeave", MinimapButton_OnLeave);
    self.MinimapButton:SetScript("OnClick", MinimapButton_OnClick);
    self.MinimapButton:SetScript("OnDragStart", MinimapButton_OnDragStart);
    self.MinimapButton:SetScript("OnDragStop", MinimapButton_OnDragStop);

    local t = self.MinimapButton:CreateTexture("$parentIcon", "BORDER");
    t:SetTexture("Interface\\TargetingFrame\\TargetDead");
    t:SetWidth(20);
    t:SetHeight(20);
    t:SetPoint("CENTER", -2, 2);

    local t = self.MinimapButton:CreateTexture(nil, "OVERLAY");
    t:SetTexture("Interface\\Minimap\\Minimap-TrackingBorder");
    t:SetWidth(52);
    t:SetHeight(52);
    t:SetPoint("TOPLEFT");
  end

  --
  -- MainFrame
  --

  do
    self.MainFrame = CreateFrame("Frame", "FLer_MainFrame", UIParent);
    self.MainFrame:Hide();
    self.MainFrame:SetWidth(254);
    self.MainFrame:SetHeight(30);
    self.MainFrame:SetPoint("CENTER");
    self.MainFrame:SetToplevel(true);
    self.MainFrame:SetMovable(true);
    self.MainFrame:SetClampedToScreen(true);
    self.MainFrame:EnableMouse(true);
    self.MainFrame:SetScript("OnHide", MainFrame_OnHide);
  end

  -- 
  -- TitleFrame
  --

  do
    self.TitleFrame = CreateFrame("Frame", nil, self.MainFrame);
    self.TitleFrame:SetHeight(30);
    self.TitleFrame:SetPoint("TOPLEFT");
    self.TitleFrame:SetPoint("TOPRIGHT");
    self.TitleFrame:SetBackdrop(backdrop);
    self.TitleFrame:EnableMouse(true);
    self.TitleFrame:SetScript("OnMouseDown", TitleFrame_OnMouseDown);
    self.TitleFrame:SetScript("OnMouseUp", TitleFrame_OnMouseUp);

    local f = self.TitleFrame:CreateFontString(nil, "ARTWORK", "GameFontNormal");
    f:SetHeight(16);
    f:SetPoint("CENTER");
    f:SetText(format("FyLooter %d.%d.%d", FyLooter.Version.Major, FyLooter.Version.Minor, FyLooter.Version.Patch));
  end

  -- 
  -- ScrollArea
  --

  do
    self.ScrollArea = CreateFrame("Frame", nil, self.MainFrame);
    self.ScrollArea:Hide();
    self.ScrollArea:SetHeight(16 * self.SCROLL_ITEM_COUNT + 8);
    self.ScrollArea:SetPoint("TOPLEFT", self.TitleFrame, "BOTTOMLEFT");
    self.ScrollArea:SetPoint("TOPRIGHT", self.TitleFrame, "BOTTOMRIGHT");
    self.ScrollArea:SetScript("OnShow", ScrollArea_OnShow);
    self.ScrollArea:SetScript("OnHide", ScrollArea_OnHide);
  end

  -- 
  -- ScrollView
  --

  do
    self.ScrollView = CreateFrame("Frame", nil, self.ScrollArea);
    self.ScrollView:SetPoint("TOPLEFT");
    self.ScrollView:SetPoint("BOTTOMRIGHT");
    self.ScrollView:SetBackdrop(backdrop);
    self.ScrollView:EnableMouseWheel(true);
    self.ScrollView:SetScript("OnMouseWheel", ScrollView_OnMouseWheel);
  end

  -- 
  -- ScrollBar
  --

  do
    self.ScrollBar = CreateFrame("Frame", nil, self.ScrollArea);
    self.ScrollBar:Hide();
    self.ScrollBar:SetWidth(24);
    self.ScrollBar:SetPoint("TOPRIGHT");
    self.ScrollBar:SetPoint("BOTTOMRIGHT");
    self.ScrollBar:SetBackdrop(backdrop);
    self.ScrollBar:SetScript("OnShow", ScrollBar_OnShow);
    self.ScrollBar:SetScript("OnHide", ScrollBar_OnHide);
  end

  -- 
  -- ScrollUpButton
  --
  
  do
    self.ScrollUpButton = CreateFrame("Button", nil, self.ScrollBar, "UIPanelScrollUpButtonTemplate");
    self.ScrollUpButton:SetWidth(16);
    self.ScrollUpButton:SetHeight(16);
    self.ScrollUpButton:SetPoint("TOP", 0, -4);
    self.ScrollUpButton:SetScript("OnClick", ScrollUpButton_OnClick);
  end

  --
  -- ScrollDownButton
  --

  do
    self.ScrollDownButton = CreateFrame("Button", nil, self.ScrollBar, "UIPanelScrollDownButtonTemplate");
    self.ScrollDownButton:SetWidth(16);
    self.ScrollDownButton:SetHeight(16);
    self.ScrollDownButton:SetPoint("BOTTOM", 0, 4);
    self.ScrollDownButton:SetScript("OnClick", ScrollDownButton_OnClick);
  end

  -- 
  -- ScrollSlider
  --

  do
    self.ScrollSlider = CreateFrame("Slider", nil, self.ScrollBar);
    self.ScrollSlider:SetWidth(16);
    self.ScrollSlider:SetPoint("TOP", self.ScrollUpButton, "BOTTOM");
    self.ScrollSlider:SetPoint("BOTTOM", self.ScrollDownButton, "TOP");
    self.ScrollSlider:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob");
    self.ScrollSlider:SetValueStep(1);
    self.ScrollSlider:SetMinMaxValues(0, 0);
    self.ScrollSlider:SetValue(0);
    self.ScrollSlider:SetScript("OnValueChanged", ScrollSlider_OnValueChanged);

    local t = self.ScrollSlider:GetThumbTexture();
    t:SetWidth(16);
    t:SetHeight(16);
    t:SetTexCoord(0.25, 0.75, 0.25, 0.75);
  end

  -- 
  -- ScrollItems
  --

  do
    self.ScrollItems = {};

    for i = 1, self.SCROLL_ITEM_COUNT do
      local f = CreateFrame("Button", nil, FyLooter.Gui.ScrollView);
      f:SetID(i);
      f:SetHeight(16);
      f:SetPoint("LEFT", 4, 0);
      f:SetPoint("RIGHT", -4, 0);
      f:SetPoint("TOP", 0, 16 * (1 - i) - 4);
      f:SetNormalTexture("Interface\\AddOns\\FyLooter\\Textures\\BantoBar");
      f:SetHighlightTexture("Interface\\FriendsFrame\\UI-FriendsFrame-HighlightBar", "ADD");
      f:SetScript("OnClick", ScrollItem_OnClick);

      local t = f:GetNormalTexture();
      t:SetVertexColor(0.5, 0.5, 0.5, 0.5);

      f.ExpandButton = CreateFrame("Button", nil, f);
      f.ExpandButton:SetWidth(16);
      f.ExpandButton:SetHeight(16);
      f.ExpandButton:SetPoint("LEFT", 2, 0);
      f.ExpandButton:SetHighlightTexture("Interface\\Buttons\\UI-PlusButton-Hilight", "ADD");
      f.ExpandButton:SetScript("OnClick", ExpandButton_OnClick);
    
      f.NameLabel = f:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall");
      f.NameLabel:SetWidth(78);
      f.NameLabel:SetHeight(16);
      f.NameLabel:SetPoint("LEFT", f.ExpandButton, "RIGHT", 4, 0);
      f.NameLabel:SetJustifyH("LEFT");

      f.LevelLabel = f:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall");
      f.LevelLabel:SetWidth(20);
      f.LevelLabel:SetHeight(16);
      f.LevelLabel:SetPoint("LEFT", f.NameLabel, "RIGHT", 4, 0);
    
      f.ClassLabel = f:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall");
      f.ClassLabel:SetHeight(16);
      f.ClassLabel:SetPoint("LEFT", f.LevelLabel, "RIGHT", 4, 0);
      f.ClassLabel:SetPoint("RIGHT", -4, 0);
      f.ClassLabel:SetJustifyH("LEFT");

      self.ScrollItems[i] = f;
    end
  end

  --
  -- LootFrame
  --

  do
    self.LootFrame = CreateFrame("Frame", nil, self.MainFrame);
    self.LootFrame:Hide();
    self.LootFrame:SetHeight(52);
    self.LootFrame:SetPoint("TOPLEFT", self.TitleFrame, "BOTTOMLEFT");
    self.LootFrame:SetPoint("TOPRIGHT", self.TitleFrame, "BOTTOMRIGHT");
    self.LootFrame:SetBackdrop(backdrop);
    self.LootFrame:SetScript("OnShow", LootFrame_OnShow);
    self.LootFrame:SetScript("OnHide", LootFrame_OnHide);

    local f = CreateFrame("Frame", nil, self.LootFrame);
    f:SetWidth(38);
    f:SetHeight(38);
    f:SetPoint("LEFT", 7, 0);
--    f:SetBackdrop({
--      edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
--      edgeSize = 16,
--      insets   = {},
--    });
    f:EnableMouse(true);
    f:SetScript("OnEnter", LootIcon_OnEnter);
    f:SetScript("OnLeave", LootIcon_OnLeave);

    self.LootIcon = f:CreateTexture(nil);
    self.LootIcon:SetAllPoints(f);

    self.LootLabel = self.LootFrame:CreateFontString(nil, "ARTWORK", "GameFontNormal");
    self.LootLabel:SetHeight(38);
    self.LootLabel:SetPoint("LEFT", self.LootIcon, "RIGHT", 7, 0);
    self.LootLabel:SetPoint("RIGHT", -7, 0);
    self.LootLabel:SetJustifyH("LEFT");
  end

  --
  -- MasterFrame
  --

  do
    self.MasterFrame = CreateFrame("Frame", nil, self.MainFrame);
    self.MasterFrame:Hide();
    self.MasterFrame:SetHeight(36);
    self.MasterFrame:SetPoint("TOPLEFT", self.LootFrame, "BOTTOMLEFT");
    self.MasterFrame:SetPoint("TOPRIGHT", self.LootFrame, "BOTTOMRIGHT");
    self.MasterFrame:SetBackdrop(backdrop);
    self.MasterFrame:SetScript("OnShow", MasterFrame_OnShow);
    self.MasterFrame:SetScript("OnHide", MasterFrame_OnHide);

    self.PayButton = CreateFrame("Button", nil, self.MasterFrame, "UIPanelButtonGrayTemplate");
    self.PayButton:SetWidth(80);
    self.PayButton:SetHeight(22);
    self.PayButton:SetPoint("LEFT", 7, 0);
    self.PayButton:SetText("Pay Loot");
    self.PayButton:SetScript("OnClick", PayButton_OnClick);
    self.PayButton:Disable();

    local t = self.PayButton:GetNormalTexture();
    t:SetVertexColor(0.5, 1, 0.5);
    local t = self.PayButton:GetPushedTexture();
    t:SetVertexColor(0.5, 1, 0.5);

    self.FreeButton = CreateFrame("Button", nil, self.MasterFrame, "UIPanelButtonGrayTemplate");
    self.FreeButton:SetWidth(80);
    self.FreeButton:SetHeight(22);
    self.FreeButton:SetPoint("CENTER");
    self.FreeButton:SetText("Free Loot");
    self.FreeButton:SetScript("OnClick", FreeButton_OnClick);
    self.FreeButton:Disable();

    local t = self.FreeButton:GetNormalTexture();
    t:SetVertexColor(0.5, 0.5, 1);
    local t = self.FreeButton:GetPushedTexture();
    t:SetVertexColor(0.5, 0.5, 1);

    self.CloseButton = CreateFrame("Button", nil, self.MasterFrame, "UIPanelButtonGrayTemplate");
    self.CloseButton:SetWidth(80);
    self.CloseButton:SetHeight(22);
    self.CloseButton:SetPoint("RIGHT", -7, 0);
    self.CloseButton:SetText("Cancel");
    self.CloseButton:SetScript("OnClick", CloseButton_OnClick);

    local t = self.CloseButton:GetNormalTexture();
    t:SetVertexColor(1, 0.5, 0.5);
    local t = self.CloseButton:GetPushedTexture();
    t:SetVertexColor(1, 0.5, 0.5);
  end

  -- 
  -- RollFrame
  --

  do
    self.RollFrame = CreateFrame("Frame", nil, self.MainFrame);
    self.RollFrame:Hide();
    self.RollFrame:SetHeight(36);
    self.RollFrame:SetPoint("TOPLEFT", self.LootFrame, "BOTTOMLEFT");
    self.RollFrame:SetPoint("TOPRIGHT", self.LootFrame, "BOTTOMRIGHT");
    self.RollFrame:SetBackdrop(backdrop);
    self.RollFrame:SetScript("OnShow", RollFrame_OnShow);
    self.RollFrame:SetScript("OnHide", RollFrame_OnHide);

    self.NeedButton = CreateFrame("Button", nil, self.RollFrame, "UIPanelButtonGrayTemplate");
    self.NeedButton:SetWidth(80);
    self.NeedButton:SetHeight(22);
    self.NeedButton:SetPoint("LEFT", 7, 0);
    self.NeedButton:SetText("Need");
    self.NeedButton:SetScript("OnClick", NeedButton_OnClick);

    local t = self.NeedButton:GetNormalTexture();
    t:SetVertexColor(0.5, 1, 0.5);
    local t = self.NeedButton:GetPushedTexture();
    t:SetVertexColor(0.5, 1, 0.5);

    self.GreedButton = CreateFrame("Button", nil, self.RollFrame, "UIPanelButtonGrayTemplate");
    self.GreedButton:SetWidth(80);
    self.GreedButton:SetHeight(22);
    self.GreedButton:SetPoint("CENTER");
    self.GreedButton:SetText("Greed");
    self.GreedButton:SetScript("OnClick", GreedButton_OnClick);

    local t = self.GreedButton:GetNormalTexture();
    t:SetVertexColor(0.5, 0.5, 1);
    local t = self.GreedButton:GetPushedTexture();
    t:SetVertexColor(0.5, 0.5, 1);

    self.PassButton = CreateFrame("Button", nil, self.RollFrame, "UIPanelButtonGrayTemplate");
    self.PassButton:SetWidth(80);
    self.PassButton:SetHeight(22);
    self.PassButton:SetPoint("RIGHT", -7, 0);
    self.PassButton:SetText("Pass");
    self.PassButton:SetScript("OnClick", PassButton_OnClick);

    local t = self.PassButton:GetNormalTexture();
    t:SetVertexColor(1, 0.5, 0.5);
    local t = self.PassButton:GetPushedTexture();
    t:SetVertexColor(1, 0.5, 0.5);
  end

  -- 
  -- AdminFrame
  --

  do
    self.AdminFrame = CreateFrame("Frame", nil, self.MainFrame);
    self.AdminFrame:Hide();
    self.AdminFrame:SetHeight(58);
    self.AdminFrame:SetPoint("TOPLEFT", self.ScrollArea, "BOTTOMLEFT");
    self.AdminFrame:SetPoint("TOPRIGHT", self.ScrollArea, "BOTTOMRIGHT");
    self.AdminFrame:SetBackdrop(backdrop);
    self.AdminFrame:SetScript("OnShow", AdminFrame_OnShow);
    self.AdminFrame:SetScript("OnHide", AdminFrame_OnHide);

    self.InsertButton = CreateFrame("Button", nil, self.AdminFrame, "UIPanelButtonTemplate");
    self.InsertButton:SetWidth(80);
    self.InsertButton:SetHeight(22);
    self.InsertButton:SetPoint("TOPLEFT", 7, -7);
    self.InsertButton:SetText("Insert");
    self.InsertButton:SetScript("OnClick", InsertButton_OnClick);

    self.RemoveButton = CreateFrame("Button", nil, self.AdminFrame, "UIPanelButtonTemplate");
    self.RemoveButton:SetWidth(80);
    self.RemoveButton:SetHeight(22);
    self.RemoveButton:SetPoint("BOTTOMLEFT", 7, 7);
    self.RemoveButton:SetText("Remove");
    self.RemoveButton:SetScript("OnClick", RemoveButton_OnClick);
    self.RemoveButton:Disable();

    self.UpButton = CreateFrame("Button", nil, self.AdminFrame, "UIPanelButtonTemplate");
    self.UpButton:SetWidth(80);
    self.UpButton:SetHeight(22);
    self.UpButton:SetPoint("TOPRIGHT", -7, -7);
    self.UpButton:SetText("Up");
    self.UpButton:SetScript("OnClick", UpButton_OnClick);
    self.UpButton:Disable();

    self.DownButton = CreateFrame("Button", nil, self.AdminFrame, "UIPanelButtonTemplate");
    self.DownButton:SetWidth(80);
    self.DownButton:SetHeight(22);
    self.DownButton:SetPoint("BOTTOMRIGHT", -7, 7);
    self.DownButton:SetText("Down");
    self.DownButton:SetScript("OnClick", DownButton_OnClick);
    self.DownButton:Disable();
  end

  -- 
  -- InsertFrame
  -- 

  do
    self.InsertFrame = CreateFrame("Frame", nil, self.MainFrame);
    self.InsertFrame:Hide();
    self.InsertFrame:SetHeight(58);
    self.InsertFrame:SetPoint("TOPLEFT", self.ScrollArea, "BOTTOMLEFT");
    self.InsertFrame:SetPoint("TOPRIGHT", self.ScrollArea, "BOTTOMRIGHT");
    self.InsertFrame:SetBackdrop(backdrop);
    self.InsertFrame:SetScript("OnShow", InsertFrame_OnShow);
    self.InsertFrame:SetScript("OnHide", InsertFrame_OnHide);

    self.PlayerEditBox = CreateFrame("EditBox", nil, self.InsertFrame);
    self.PlayerEditBox:SetHeight(22);
    self.PlayerEditBox:SetPoint("TOPLEFT", 85, -7);
    self.PlayerEditBox:SetPoint("TOPRIGHT", -7, -7);
    self.PlayerEditBox:SetTextInsets(7, 7, 0, 0);
    self.PlayerEditBox:SetBackdrop(backdrop);
    self.PlayerEditBox:SetFontObject(ChatFontNormal);

    local f = self.PlayerEditBox:CreateFontString(nil, "ARTWORK", "GameFontNormal");
    f:SetHeight(22);
    f:SetWidth(78);
    f:SetPoint("RIGHT", self.PlayerEditBox, "LEFT", -7, 0);
    f:SetJustifyH("RIGHT");
    f:SetText("Player:");

    self.CharacterEditBox = CreateFrame("EditBox", nil, self.InsertFrame);
    self.CharacterEditBox:SetHeight(22);
    self.CharacterEditBox:SetPoint("BOTTOMLEFT", 85, 7);
    self.CharacterEditBox:SetPoint("BOTTOMRIGHT", -7, 7);
    self.CharacterEditBox:SetTextInsets(7, 7, 0, 0);
    self.CharacterEditBox:SetBackdrop(backdrop);
    self.CharacterEditBox:SetFontObject(ChatFontNormal);

    local f = self.CharacterEditBox:CreateFontString(nil, "ARTWORK", "GameFontNormal");
    f:SetHeight(22);
    f:SetWidth(78);
    f:SetPoint("RIGHT", self.CharacterEditBox, "LEFT", -7, 0);
    f:SetJustifyH("RIGHT");
    f:SetText("Character:");
  end

  -- 
  -- ControlFrame
  -- 

  do
    self.ControlFrame = CreateFrame("Frame", nil, self.MainFrame);
    self.ControlFrame:Hide();
    self.ControlFrame:SetHeight(36);
    self.ControlFrame:SetPoint("BOTTOMLEFT");
    self.ControlFrame:SetPoint("BOTTOMRIGHT");
    self.ControlFrame:SetBackdrop(backdrop);
    self.ControlFrame:SetScript("OnShow", ControlFrame_OnShow);
    self.ControlFrame:SetScript("OnHide", ControlFrame_OnHide);

    self.OkButton = CreateFrame("Button", nil, self.ControlFrame, "UIPanelButtonTemplate");
    self.OkButton:SetWidth(80);
    self.OkButton:SetHeight(22);
    self.OkButton:SetPoint("CENTER");
    self.OkButton:SetText("Close");

    self.CancelButton = CreateFrame("Button", nil, self.ControlFrame, "UIPanelButtonTemplate");
    self.CancelButton:Hide();
    self.CancelButton:SetWidth(80);
    self.CancelButton:SetHeight(22);
    self.CancelButton:SetPoint("RIGHT", -7, 0);
    self.CancelButton:SetText("Cancel");
  end

  -- 
  --
  --


end

-- ------------------------------------------------------------------------- --

